package com.codefish.framework.spring.beans.factory.support;

import com.codefish.framework.spring.beans.factory.IFactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 实现对单例的{@link com.codefish.framework.spring.beans.factory.IFactoryBean}的创建的实例进行注册操作
 *
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/10/08 下午 04:13
 */
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
    /**
     * 用于注册返回单例的FactoryBean的实例
     */
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);


    /**
     * 尝试获取FactoryBean对应的实例
     */
    protected Object getObjectFromFactoryBean(IFactoryBean<?> factory, String beanName) {
        Object object;
        if (factory.isSingleton() && containsBean(beanName)) {
            //如果FactoryBean创建的实例为单例且FactoryBean自身为单例,则需要尝试从cache中获取实例
            Object alreadyObject = factoryBeanObjectCache.get(beanName);
            if (alreadyObject != null) {
                object = alreadyObject;
            } else {
                //若从cache中获取不到，则需要创建实例并且注册到cache中
                object = doGetObjectFromFactoryBean(factory, beanName);
                if (containsBean(beanName)) {
                    this.factoryBeanObjectCache.put(beanName, object);
                }
            }
        } else {
            //直接创建实例并返回
            object = doGetObjectFromFactoryBean(factory, beanName);
        }
        return object;
    }

    /**
     * FactoryBean直接创建一个新的实例
     */
    private Object doGetObjectFromFactoryBean(IFactoryBean<?> factory, String beanName) {
        return factory.getObject();
    }

    @Override
    public void destroySingleton(String beanName) {
        super.destroySingleton(beanName);
        this.factoryBeanObjectCache.remove(beanName);
    }

    @Override
    public void destroySingletons() {
        super.destroySingletons();
        this.factoryBeanObjectCache.clear();
    }


}
